package world.snowcrystal.dto;


import lombok.Getter;
import lombok.Setter;
import org.springframework.util.Assert;
import world.snowcrystal.Enum.ApplicationStatusCodeEnum;

import java.io.Serializable;
@Getter
@Setter
public class ApplicationMessage<T> implements Serializable {

    private static final long serialVersionUID = 112941234L;

    private String message;

    private Integer code;

    private T data;

    public ApplicationMessage(String message) {
        Assert.notNull(message, "Message must not be null");
        this.message = message;
    }
    public ApplicationMessage(String message, ApplicationStatusCodeEnum code) {
        Assert.notNull(message, "Message must not be null");
        this.message = message;
        this.code = code.getCode();
    }
    public ApplicationMessage(ApplicationStatusCodeEnum code, String message, T data) {
        Assert.notNull(message, "Message must not be null");
        this.code = code.getCode();
        this.message = message;
        this.data = data;
    }
    public ApplicationMessage(){}



    static public <T> ApplicationMessage<T> ok(String msg, T data){
        Assert.notNull(msg, "Message must not be null");
        return new ApplicationMessage<>(ApplicationStatusCodeEnum.OK,msg,data);
    }
    static public  ApplicationMessage<Void> ok(String msg){
        Assert.notNull(msg, "Message must not be null");
        return ok(msg,null);
    }
    static public <T> ApplicationMessage<T> notFound(String msg){
        Assert.notNull(msg, "Message must not be null");
        return new ApplicationMessage<>(ApplicationStatusCodeEnum.NOT_FOUND,msg,null);
    }
    static public <T> ApplicationMessage<T> notFound(String msg, T data){
        Assert.notNull(msg, "Message must not be null");
        return new ApplicationMessage<>(ApplicationStatusCodeEnum.NOT_FOUND,msg,data);
    }


    static public <T> ApplicationMessage<T> needLogin(String msg, T data){
    Assert.notNull(msg, "Message must not be null");
    return new ApplicationMessage<>(ApplicationStatusCodeEnum.NEED_AUTHENTICATION,msg,data);
    }

    static public <T> ApplicationMessage<T> needLogin(String msg){
        Assert.notNull(msg, "Message must not be null");
        return needLogin(msg,null);
    }


    static public <T> ApplicationMessage<T> badCredentials(String msg, T data){
        return new ApplicationMessage<>(ApplicationStatusCodeEnum.BAD_CREDENTIALS,msg,data);
    }
    static public <T> ApplicationMessage<T> badCredentials(String msg){
        return badCredentials(msg,null);
    }

    static public <T> ApplicationMessage<T> noCredentialsProvided(String msg, T data){
        return new ApplicationMessage<>(ApplicationStatusCodeEnum.NO_CREDENTIALS_PROVIDED,msg,data);
    }
    static public <T> ApplicationMessage<T> noCredentialsProvided(String msg){
        return noCredentialsProvided(msg,null);
    }


    static public <T> ApplicationMessage<T> hasMore(String msg, T data){
        return new ApplicationMessage<>(ApplicationStatusCodeEnum.HAS_MORE,msg,data);
    }
    static public <T> ApplicationMessage<T> hasMore(String msg){
        return hasMore(msg,null);
    }

    static public <T> ApplicationMessage<T> badRequest(String msg, T data){
        return new ApplicationMessage<>(ApplicationStatusCodeEnum.BAD_REQUEST,msg,data);
    }
    static public <T> ApplicationMessage<T> badRequest(String msg){
        return badRequest(msg,null);
    }

    static public <T> ApplicationMessage<T> created(String msg, T data){
        return new ApplicationMessage<>(ApplicationStatusCodeEnum.CREATED,msg,data);
    }
    static public <T> ApplicationMessage<T> created(String msg){
        return badRequest(msg,null);
    }
    static public <T> ApplicationMessage<T> error(String msg, T data){
        return new ApplicationMessage<>(ApplicationStatusCodeEnum.INNER_ERROR,msg,data);
    }
    static public <T> ApplicationMessage<T> error(String msg){
        return badRequest(msg,null);
    }
    static public ApplicationMessage<Void> useNative(String msg){
        return new ApplicationMessage<>(msg,ApplicationStatusCodeEnum.USE_NATIVE);
    }

    static public ApplicationMessage<Void> alreadyExists(String msg){
        return new ApplicationMessage<>(msg,ApplicationStatusCodeEnum.ALREADY_EXISTS);
    }
    static public ApplicationMessage<Void> operationFailed(String msg){
        return new ApplicationMessage<>(msg,ApplicationStatusCodeEnum.OPERATION_FAILED);
    }

}
